<?php
namespace Snitso\IO\PcntlModel;

class Worker
{
    /**
     * @var resource $socket
     */
    protected $socket;

    /**
     * @var \Closure
     */
    public $onConnect;

    /**
     * @var \Closure
     */
    public $onReceive;

    protected $workerNum = 4;

    public function __construct(string $localSocket)
    {
        $socket = stream_socket_server($localSocket, $errno, $errstr);

        if (! $socket) {
            echo $errstr . PHP_EOL;
            exit;
        }

        stream_set_blocking($socket, 0);

        $this->socket = $socket;
    }

    public function start()
    {
        $this->fork();
    }

    protected function fork()
    {
        $pidArr = [];

        for ($i = 0; $i < $this->workerNum; $i++) {
            $sonPid = pcntl_fork();

            if ($sonPid === -1) {
                exit('fork 子进程错误' . PHP_EOL);
            }
            elseif ($sonPid === 0) {
                $this->debug('子进程ID：'. posix_getpid());
                $this->accept();
                exit;
            } else {
                // 父进程空间
                $pidArr[] = $sonPid;
            }
        }

        while (count($pidArr) > 1) {
            foreach ($pidArr as $k => $pid) {
                $res = pcntl_waitpid($pid, $status, WNOHANG);

                if ($res > 0 || $res === -1) {
                    unset($pidArr[$k]);
                }
            }
        }
    }

    protected function accept()
    {
        while (true) {
            $conn = stream_socket_accept($this->socket);

            if ($conn === false) {
                echo '连接失败' . PHP_EOL;
                exit;
            }

            ($this->onConnect)($this, $conn);

            $data = fread($conn, 1024);

            ($this->onReceive)($this, $conn, $data);

            fclose($conn);
        }
    }

    public function send($conn, string $content)
    {
        $response = "HTTP/1.1 200 OK\r\n";
        $response .= "Content-Type: text/html;charset=UTF-8\r\n";
        $response .= "Connection: keep-alive\r\n";
        $response .= "Content-length: ".strlen($content)."\r\n\r\n";
        $response .= $content;
        fwrite($conn, $response);
    }

    protected function debug(string $str, $data = null)
    {
        echo $str . PHP_EOL;

        if ($data) {
            print_r($data);
            echo "\r\n";
        }
    }
}